package com.wasion.gydpe.ice;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

//代理、状态、通知接口
class CMonitorObject {
	Ice.ObjectPrx proxy;
	short state;
	ICommExpNotify notify;

	CMonitorObject(Ice.ObjectPrx aProxy, short aState, ICommExpNotify aNotify) {
		proxy = aProxy;
		state = aState;
		notify = aNotify;
	}
};

public class CHeartbeatMonitor implements Runnable {
	private static final int ICE_TIMEOUT = 1000 * 20; // 20秒
	private static final int SLEEP_TIME = 60 * 10 * 1000; // 10分钟

	private Map<String, CMonitorObject> _clients;
	private boolean _destroy;

	private static CHeartbeatMonitor _instance;
	private static Lock _mutex = new ReentrantLock();

	public static CHeartbeatMonitor getInstance() {
		if (null == _instance) {
			_mutex.lock();
			if (null == _instance) {
				_instance = new CHeartbeatMonitor();
			}
			_mutex.unlock();
		}
		return _instance;
	}

	private CHeartbeatMonitor() {
		_destroy = false;
		_clients = new HashMap<String, CMonitorObject>();
	}

	// 增加监视对象
	public void attach(String name, Ice.ObjectPrx pObj, ICommExpNotify notify,
			short state) {
		_mutex.lock();
		_clients.put(name, new CMonitorObject(pObj.ice_timeout(ICE_TIMEOUT),
				state, notify));
		_mutex.unlock();
	}

	// 解除监视对象
	public void detach(String name) {
		_mutex.lock();
		_clients.remove(name);
		_mutex.unlock();
		;
	}

	// 检测一轮心跳
	private void heartBeat() {
		short bState = ICommExpNotify.STATE_OFF;
		if (_destroy || _clients.isEmpty()) {
			return;
		} else {
			_mutex.lock();
			if (!(_destroy || _clients.isEmpty())) {
				Iterator<Entry<String, CMonitorObject>> it = _clients
						.entrySet().iterator();
				while ((it.hasNext()) && (!_destroy)) {
					Map.Entry<String, CMonitorObject> entry = (Map.Entry<String, CMonitorObject>) it
							.next();
					CMonitorObject value = (CMonitorObject) entry.getValue();
					try // 试ping
					{
						value.proxy.ice_ping();
					} catch (Exception e) // ping不通
					{
						bState = ICommExpNotify.STATE_OFF;
					}

					if ((value.notify != null) // 有通知
							&& (value.state != bState)) // 且状态发生改变
					{
						value.notify.OnExpNotify(value.proxy, bState);
					}
					value.state = bState; // 改变状态
				}
			}
			_mutex.unlock();
		}
	}

	// 线程运行
	public void run() {
		while (!_destroy) {
			heartBeat();
			try {
				Thread.sleep(SLEEP_TIME);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				_destroy = true;
			}
		}
	}

	public void stop() {
		_destroy = true;
	}
}
